//import java.io.Serializable;
import java.util.ArrayList;

import common.*;

/**
 * This class will be used to keep the record of critical section requests / critical section in use. 
 */
public class CriticalSectionRecord{
	//private static final long serialVersionUID = -2923864330170081815L;
	private long request_time_ms;		// requested time == the timestamp of msg
	private int requester;				// id of requester
	protected int owner;				// id of owner - protected
	private String location;
	private String name;
	protected int duration_ms;		// protected
	private int opr_type;			// operation type = either Def.ME_OPR_READONLY == Def.REQUEST_READ
									//						or Def.ME_OPR_WRITE == Def.REQUEST_WRITE
	protected ArrayList<Integer> granted_by;		// i've got GRANTed by these processes
													// protected -- this is solely for the TOKENLESS scheme: list of granted nodes
													// size() should be 1 when opr_type is WR, otherwise size() should be 1+
	protected long grant_time_ms;	// timestamp that the process actually starts accessing
	protected int trial_left; 		// for FT:crc corrupt
	protected int crc;				// crc error checking code -- comes from the resource
	
	// constructor
	protected CriticalSectionRecord( Message msg ){
		request_time_ms = msg.get_timestamp();	// requested time == the timestamp of msg
		requester = msg.get_sender_id();		// id of requester
		opr_type = msg.get_type();				// opr type = either Def.ME_OPR_READONLY == Def.REQUEST_READ  or  Def.ME_OPR_WRITE == Def.REQUEST_WRITE
		
		owner = Def.NOT_ASSIGNED;							// it will be changed in the future according to the owner's reponse + the proximity (for replicas)		
		trial_left = Conf.MAX_TRIAL; 		// for FT:crc corrupt
		
		if( Conf.ME_SCHEME == Def.ME_TOKENLESS ) granted_by = new ArrayList<Integer>();		// list of the concurrent users  ---  size() should be 1 when opr_type is WR, otherwise size() should be 1+
		else if( Conf.ME_SCHEME == Def.ME_TOKEN );
		
		// getting name and location
		if( msg.get_content() != null ){
			int index = msg.get_content().lastIndexOf( '/' );
			if( index == -1 ) index = msg.get_content().lastIndexOf( '\\' );	// don't use it - let's stick to UNIX' way
			
			if( index == -1 ){
				location = "/";
				name = msg.get_content();
			}else{
				location = msg.get_content().substring( 0, index + 1  );
				name = msg.get_content().substring( index + 1  );
			}
		}
		
		// grant_time_ms and crc will be set later on.
		grant_time_ms = Def.NOT_ASSIGNED;
	}
	
	// accessors
	public String get_location_n_name(){ return location + name; }
	public long get_request_time(){ return request_time_ms; }
	public long get_grant_time(){ return grant_time_ms; }
	public int get_operation_type(){ return opr_type; }
	public int get_owner(){ return owner; }
	public int get_requester(){ return requester; }
	
	public long get_time_left(){
		if( grant_time_ms == Def.NOT_ASSIGNED ) return 5000;
		else if( duration_ms == Def.NOT_ASSIGNED ) return 5000;
		else{
			long temp = System.currentTimeMillis() - grant_time_ms - duration_ms;
			if( temp > 0 ) return temp;
			else return 5000;
		}
	}
}


// SAVED JUST IN CASE
//protected CriticalSectionRecord( long _request_time_ms, int _requester,
//int _owner, String _location, String _name, int _duration_ms, int _opr_type, long _grant_time_ms ){
//request_time_ms = _request_time_ms;
//requester = _requester;
//
//owner = _owner;
//location = _location;
//name = _name;
//duration_ms = _duration_ms;
//opr_type = _opr_type;
//
//if( Conf.ME_SCHEME == Def.ME_TOKENLESS ) granted_by = new ArrayList<Integer>();
//grant_time_ms = _grant_time_ms;
//trial_left = Conf.MAX_TRIAL; // for FT:crc corrupt 
//}